import React, { useEffect, useRef, useState } from "react";
import * as echarts from "echarts";

export interface PricePoint {
  t: number;
  price: number;
  volume?: number;
}

interface StockChartProps {
  series: (PricePoint | null)[]; // 允许null值，表示该时间点暂无数据
  mode: "intraday" | "kline";
  width?: number;
  height?: number;
  showVolume?: boolean;
}

/**
 * 专业股票图表组件 - 使用 ECharts
 * 支持分时图和K线图，类似同花顺风格
 */
export const StockChart: React.FC<StockChartProps> = ({
  series,
  mode,
  width = 800,
  height = 400,
  showVolume = true,
}) => {
  const chartRef = useRef<HTMLDivElement>(null);
  const chartInstanceRef = useRef<echarts.ECharts | null>(null);
  const [error, setError] = useState<string | null>(null);
  const prevOpenPriceRef = useRef<number | null>(null); // 跟踪之前的开盘价

  // 初始化图表
  useEffect(() => {
    let chart: echarts.ECharts | null = null;
    let handleResize: (() => void) | null = null;

    const initChart = () => {
      try {
        if (!chartRef.current) {
          console.warn("StockChart: chartRef.current is null");
          return;
        }

        // 清理之前的图表实例
        if (chartInstanceRef.current) {
          try {
            chartInstanceRef.current.dispose();
          } catch (e) {
            console.error("Error disposing previous chart:", e);
          }
          chartInstanceRef.current = null;
        }

        // 检查 ECharts 是否加载
        if (typeof echarts === "undefined" || !echarts.init) {
          throw new Error("ECharts 库未正确加载，请刷新页面");
        }

        // 创建 ECharts 实例
        chart = echarts.init(chartRef.current, "dark");
        if (!chart) {
          throw new Error("无法创建图表实例");
        }

        chartInstanceRef.current = chart;

        // 响应式调整
        handleResize = () => {
          if (chartInstanceRef.current && chartRef.current) {
            try {
              // 确保图表尺寸与容器匹配
              chartInstanceRef.current.resize({
                width: chartRef.current.offsetWidth,
                height: chartRef.current.offsetHeight,
              });
            } catch (e) {
              console.error("Error resizing chart:", e);
            }
          }
        };

        window.addEventListener("resize", handleResize);
        
        // 初始化后立即调整一次，确保尺寸正确
        setTimeout(() => {
          handleResize();
        }, 200);
        
        setError(null);
        console.log("StockChart: 图表初始化成功");
      } catch (err) {
        console.error("Error initializing chart:", err);
        setError(err instanceof Error ? err.message : "图表初始化失败");
      }
    };

    // 延迟初始化，确保 DOM 已渲染
    const timer = setTimeout(initChart, 100);

    return () => {
      clearTimeout(timer);
      if (handleResize) {
        window.removeEventListener("resize", handleResize);
      }
      if (chartInstanceRef.current) {
        try {
          chartInstanceRef.current.dispose();
        } catch (e) {
          console.error("Error disposing chart:", e);
        }
        chartInstanceRef.current = null;
      }
    };
  }, []);

  // 更新图表数据和配置
  useEffect(() => {
    if (!chartInstanceRef.current) {
      return;
    }

    if (series.length === 0) {
      // 如果没有数据，显示空状态
      chartInstanceRef.current.setOption({
        title: {
          text: "等待数据加载...",
          left: "center",
          top: "center",
          textStyle: {
            color: "#9ca3af",
            fontSize: 14,
          },
        },
      }, false); // notMerge: false 只更新数据
      return;
    }

    try {
      // 过滤掉null值，获取有效数据点
      const validSeries = series.filter((p): p is PricePoint => p !== null);
      
      if (validSeries.length === 0) {
        chartInstanceRef.current.setOption({
          title: {
            text: "等待数据加载...",
            left: "center",
            top: "center",
            textStyle: {
              color: "#9ca3af",
              fontSize: 14,
            },
          },
        }, false);
        return;
      }
      
      // 计算开盘价（第一个非null数据点的价格，作为基准）
      const openPrice = validSeries.length > 0 ? validSeries[0].price : 0;
      
      // 如果开盘价变化了（且不为0），需要重新初始化配置（notMerge: true）
      const shouldReinit = openPrice > 0 && prevOpenPriceRef.current !== null && 
                           Math.abs(prevOpenPriceRef.current - openPrice) > 0.01; // 允许小的浮点误差
      
      // 生成交易时间段的时间标签（9:30-15:00，固定240个位置）
      const MAX_POINTS = 240;
      const generateTimeLabels = (count: number): string[] => {
        if (count === 0) return [];
        
        const labels: string[] = [];
        const startHour = 9;
        const startMinute = 30;
        const endHour = 15;
        const endMinute = 0;
        
        // 交易时间段总分钟数：9:30到15:00 = 5.5小时 = 330分钟
        const totalMinutes = (endHour - startHour) * 60 + (endMinute - startMinute);
        
        for (let i = 0; i < count; i++) {
          // 将索引映射到交易时间段
          const ratio = count > 1 ? i / (count - 1) : 0;
          const minutesFromStart = ratio * totalMinutes;
          const totalMinutesFromStart = startHour * 60 + startMinute + minutesFromStart;
          const hour = Math.floor(totalMinutesFromStart / 60);
          const minute = Math.floor(totalMinutesFromStart % 60);
          
          // 显示所有重要时刻：整点、半点、以及每15分钟
          // 9:30, 10:00, 10:15, 10:30, 10:45, 11:00, 11:15, 11:30, 11:45, 12:00, 12:15, 12:30, 12:45, 13:00, 13:15, 13:30, 13:45, 14:00, 14:15, 14:30, 14:45, 15:00
          if (minute === 0 || minute === 15 || minute === 30 || minute === 45 || i === 0 || i === count - 1) {
            labels.push(`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`);
          } else {
            labels.push('');
          }
        }
        return labels;
      };
      
      // 计算实际价格范围（用于动态调整纵坐标）
      const prices = validSeries.map((p) => p.price);
      let minPrice = prices.length > 0 ? Math.min(...prices) : 0;
      let maxPrice = prices.length > 0 ? Math.max(...prices) : 0;
      
      // 添加边距（上下各留5%的空间）
      if (minPrice > 0 && maxPrice > 0) {
        const priceRange = maxPrice - minPrice;
        const margin = priceRange * 0.05;
        minPrice = Math.max(0, minPrice - margin);
        maxPrice = maxPrice + margin;
      }
      
      if (mode === "kline") {
        // K线图配置（使用有效数据点）
        const candles = aggregateToCandles(validSeries);

        // 生成固定240个位置的时间标签
        const timeLabels = generateTimeLabels(MAX_POINTS);
        
        const option: echarts.EChartsOption = {
          backgroundColor: "transparent",
          tooltip: {
            trigger: "axis",
            axisPointer: {
              type: "cross",
            },
            backgroundColor: "rgba(15,23,42,0.95)",
            borderColor: "rgba(148,163,184,0.3)",
            textStyle: {
              color: "#e5e7eb",
            },
          },
          grid: [
            {
              left: "8%",
              right: "8%",
              top: "10%",
              bottom: showVolume ? "25%" : "15%",
              height: showVolume ? "65%" : "75%",
            },
            ...(showVolume
              ? [
                  {
                    left: "8%",
                    right: "8%",
                    top: "75%",
                    bottom: "5%",
                    height: "20%",
                  },
                ]
              : []),
          ],
          xAxis: [
            {
              type: "category",
              data: timeLabels,
              scale: false,
              boundaryGap: false,
              axisLine: { onZero: false, lineStyle: { color: "rgba(148,163,184,0.2)" } },
              splitLine: { show: true, lineStyle: { color: "rgba(148,163,184,0.1)" } },
              axisLabel: { 
                color: "#9ca3af", 
                fontSize: 11,
                formatter: (value: string) => value || '', // 只显示非空标签
              },
            },
            ...(showVolume
              ? [
                  {
                    type: "category",
                    gridIndex: 1,
                    data: timeLabels,
                    scale: false,
                    boundaryGap: false,
                    axisLine: { onZero: false, lineStyle: { color: "rgba(148,163,184,0.2)" } },
                    axisLabel: { show: false },
                    splitLine: { show: false },
                  },
                ]
              : []),
          ],
          yAxis: [
            {
              type: "value",
              min: minPrice,
              max: maxPrice,
              splitArea: {
                show: true,
                areaStyle: {
                  color: ["rgba(15,23,42,0.3)", "rgba(15,23,42,0.1)"],
                },
              },
              axisLine: { lineStyle: { color: "rgba(148,163,184,0.2)" } },
              splitLine: { lineStyle: { color: "rgba(148,163,184,0.1)" } },
              axisLabel: { 
                color: "#9ca3af", 
                fontSize: 11,
                formatter: (value: number) => value.toFixed(2),
              },
            },
            ...(showVolume
              ? [
                  {
                    scale: true,
                    gridIndex: 1,
                    splitNumber: 2,
                    axisLabel: { show: false },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { show: false },
                  },
                ]
              : []),
          ],
          dataZoom: candles.length > 0
            ? [
                {
                  type: "inside",
                  xAxisIndex: showVolume ? [0, 1] : [0],
                  start: Math.max(0, ((candles.length - 60) / candles.length) * 100),
                  end: 100,
                },
                {
                  show: true,
                  xAxisIndex: showVolume ? [0, 1] : [0],
                  type: "slider",
                  top: "90%",
                  start: Math.max(0, ((candles.length - 60) / candles.length) * 100),
                  end: 100,
                  handleStyle: {
                    color: "#22c55e",
                  },
                },
              ]
            : [],
          series: [
            {
              name: "K线",
              type: "candlestick",
              data: candles.map((c) => [c.open, c.close, c.low, c.high]),
              itemStyle: {
                color: "#22c55e",
                color0: "#ef4444",
                borderColor: "#22c55e",
                borderColor0: "#ef4444",
              },
            },
            ...(showVolume
              ? [
                  {
                    name: "成交量",
                    type: "bar",
                    xAxisIndex: 1,
                    yAxisIndex: 1,
                    data: candles.map((c, index) => ({
                      value: c.volume || 0,
                      itemStyle: {
                        color: candles[index].close >= candles[index].open ? "#22c55e80" : "#ef444480",
                      },
                    })),
                  },
                ]
              : []),
          ],
        };

        chartInstanceRef.current.setOption(option, shouldReinit); // 如果开盘价变化，重新初始化
        
        // 确保图表正确填充容器
        setTimeout(() => {
          if (chartInstanceRef.current && chartRef.current) {
            try {
              chartInstanceRef.current.resize({
                width: chartRef.current.offsetWidth,
                height: chartRef.current.offsetHeight,
              });
            } catch (e) {
              console.error("Error resizing chart after update:", e);
            }
          }
        }, 50);
        
        if (shouldReinit) {
          prevOpenPriceRef.current = openPrice;
        }
      } else {
        // 分时图配置
        // 创建240个位置的数据数组，null值表示该位置暂无数据
        const intradayPrices = series.map((p) => (p ? p.price : null));
        const volumes = series.map((p) => (p ? (p.volume || 0) : null));
        const validPrices = validSeries.map((p) => p.price);
        const avgPrice = validPrices.length > 0 
          ? validPrices.reduce((sum, p) => sum + p, 0) / validPrices.length 
          : 0;

        // 计算涨跌幅（使用有效数据）
        const firstValidPrice = validPrices[0] || 0;
        const lastValidPrice = validPrices[validPrices.length - 1] || 0;
        const change = lastValidPrice - firstValidPrice;
        const changePercent = firstValidPrice > 0 ? (change / firstValidPrice) * 100 : 0;
        const priceColor = change >= 0 ? "#22c55e" : "#ef4444";
        
        // 计算分时图的动态价格范围（使用有效数据）
        let intradayMinPrice = validPrices.length > 0 ? Math.min(...validPrices) : 0;
        let intradayMaxPrice = validPrices.length > 0 ? Math.max(...validPrices) : 0;
        
        // 添加边距（上下各留5%的空间）
        if (intradayMinPrice > 0 && intradayMaxPrice > 0) {
          const intradayPriceRange = intradayMaxPrice - intradayMinPrice;
          const intradayMargin = intradayPriceRange * 0.05;
          intradayMinPrice = Math.max(0, intradayMinPrice - intradayMargin);
          intradayMaxPrice = intradayMaxPrice + intradayMargin;
        }

        const option: echarts.EChartsOption = {
          backgroundColor: "transparent",
          tooltip: {
            trigger: "axis",
            axisPointer: {
              type: "cross",
            },
            backgroundColor: "rgba(15,23,42,0.95)",
            borderColor: "rgba(148,163,184,0.3)",
            textStyle: {
              color: "#e5e7eb",
            },
            formatter: (params: any) => {
              const param = Array.isArray(params) ? params[0] : params;
              const index = param.dataIndex;
              const price = intradayPrices[index];
              const volume = volumes[index];
              // 使用实际数据点的时间戳来显示时间
              const dataPoint = series[index];
              let timeLabel = '';
              if (dataPoint) {
                const date = new Date(dataPoint.t);
                const hour = date.getHours();
                const minute = date.getMinutes();
                const second = date.getSeconds();
                timeLabel = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;
              } else {
                // 如果没有实际数据点，使用时间标签数组
                const timeLabels = generateTimeLabels(MAX_POINTS);
                timeLabel = timeLabels[index] || '';
              }
              return `
                <div style="padding: 4px;">
                  <div>时间: ${timeLabel}</div>
                  <div>价格: <span style="color: ${priceColor}">${price !== null ? price.toFixed(2) : "N/A"}</span></div>
                  <div>均价: <span style="color: #fbbf24">${avgPrice.toFixed(2)}</span></div>
                  <div>成交量: ${volume !== null ? volume.toLocaleString() : 0}</div>
                </div>
              `;
            },
          },
          grid: [
            {
              left: "8%",
              right: "8%",
              top: "15%",
              bottom: showVolume ? "25%" : "15%",
              height: showVolume ? "60%" : "70%",
            },
            ...(showVolume
              ? [
                  {
                    left: "8%",
                    right: "8%",
                    top: "75%",
                    bottom: "5%",
                    height: "20%",
                  },
                ]
              : []),
          ],
          xAxis: [
            {
              type: "category",
              data: generateTimeLabels(MAX_POINTS),
              boundaryGap: false,
              axisLine: { lineStyle: { color: "rgba(148,163,184,0.2)" } },
              splitLine: { show: true, lineStyle: { color: "rgba(148,163,184,0.1)" } },
              axisLabel: { 
                color: "#9ca3af", 
                fontSize: 11,
                formatter: (value: string) => value || '', // 只显示非空标签
              },
            },
            ...(showVolume
              ? [
                  {
                    type: "category",
                    gridIndex: 1,
                    data: generateTimeLabels(MAX_POINTS),
                    boundaryGap: false,
                    axisLine: { lineStyle: { color: "rgba(148,163,184,0.2)" } },
                    axisLabel: { show: false },
                    splitLine: { show: false },
                  },
                ]
              : []),
          ],
          yAxis: [
            {
              type: "value",
              min: intradayMinPrice,
              max: intradayMaxPrice,
              position: "right",
              splitArea: {
                show: true,
                areaStyle: {
                  color: ["rgba(15,23,42,0.3)", "rgba(15,23,42,0.1)"],
                },
              },
              axisLine: { lineStyle: { color: "rgba(148,163,184,0.2)" } },
              splitLine: { lineStyle: { color: "rgba(148,163,184,0.1)" } },
              axisLabel: {
                color: "#9ca3af",
                fontSize: 11,
                formatter: (value: number) => value.toFixed(2),
              },
            },
            ...(showVolume
              ? [
                  {
                    type: "value",
                    gridIndex: 1,
                    splitNumber: 2,
                    axisLabel: { show: false },
                    axisLine: { show: false },
                    axisTick: { show: false },
                    splitLine: { show: false },
                  },
                ]
              : []),
          ],
          dataZoom:
            validSeries.length > 0
              ? [
                  {
                    type: "inside",
                    xAxisIndex: showVolume ? [0, 1] : [0],
                    start: Math.max(0, ((MAX_POINTS - 240) / MAX_POINTS) * 100),
                    end: 100,
                  },
                ]
              : [],
          series: [
            {
              name: "价格",
              type: "line",
              data: intradayPrices,
              smooth: true,
              lineStyle: {
                color: priceColor,
                width: 2,
              },
              itemStyle: {
                color: priceColor,
              },
              areaStyle: {
                color: {
                  type: "linear",
                  x: 0,
                  y: 0,
                  x2: 0,
                  y2: 1,
                  colorStops: [
                    { offset: 0, color: `${priceColor}40` },
                    { offset: 1, color: `${priceColor}08` },
                  ],
                },
              },
              symbol: "none",
              emphasis: {
                focus: "series",
              },
            },
            {
              name: "均价",
              type: "line",
              data: intradayPrices.map(() => avgPrice),
              lineStyle: {
                color: "#fbbf24",
                width: 1,
                type: "dashed",
              },
              itemStyle: {
                color: "#fbbf24",
              },
              symbol: "none",
              z: 10,
            },
            ...(showVolume
              ? [
                  {
                    name: "成交量",
                    type: "bar",
                    xAxisIndex: 1,
                    yAxisIndex: 1,
                    data: volumes.map((vol, index) => ({
                      value: vol !== null ? vol : null,
                      itemStyle: {
                        color:
                          index > 0 && 
                          intradayPrices[index] !== null && 
                          intradayPrices[index - 1] !== null &&
                          intradayPrices[index]! >= intradayPrices[index - 1]!
                            ? "#22c55e80"
                            : "#ef444480",
                      },
                    })),
                  },
                ]
              : []),
          ],
        };

        chartInstanceRef.current.setOption(option, shouldReinit); // 如果开盘价变化，重新初始化
        
        // 确保图表正确填充容器
        setTimeout(() => {
          if (chartInstanceRef.current && chartRef.current) {
            try {
              chartInstanceRef.current.resize({
                width: chartRef.current.offsetWidth,
                height: chartRef.current.offsetHeight,
              });
            } catch (e) {
              console.error("Error resizing chart after update:", e);
            }
          }
        }, 50);
        
        if (shouldReinit) {
          prevOpenPriceRef.current = openPrice;
        }
      }
      
      // 如果还没有设置过开盘价，设置它
      if (prevOpenPriceRef.current === null && openPrice > 0) {
        prevOpenPriceRef.current = openPrice;
      }
    } catch (err) {
      console.error("Error updating chart:", err);
      setError(err instanceof Error ? err.message : "图表更新失败");
    }
  }, [series, mode, showVolume]);

  // 监听容器尺寸变化
  useEffect(() => {
    if (!chartInstanceRef.current || !chartRef.current) {
      return;
    }

    // 使用 ResizeObserver 监听容器尺寸变化
    const resizeObserver = new ResizeObserver(() => {
      if (chartInstanceRef.current && chartRef.current) {
        try {
          chartInstanceRef.current.resize({
            width: chartRef.current.offsetWidth,
            height: chartRef.current.offsetHeight,
          });
        } catch (e) {
          console.error("Error resizing chart on container resize:", e);
        }
      }
    });

    resizeObserver.observe(chartRef.current);

    return () => {
      resizeObserver.disconnect();
    };
  }, []);

  // 聚合数据点为K线
  const aggregateToCandles = (points: PricePoint[]) => {
    if (points.length === 0) return [];

    const candles: Array<{
      open: number;
      high: number;
      low: number;
      close: number;
      volume: number;
    }> = [];

    const groupSize = 5;
    for (let i = 0; i < points.length; i += groupSize) {
      const group = points.slice(i, i + groupSize);
      if (group.length === 0) continue;

      const prices = group.map((p) => p.price);
      const volumes = group.map((p) => p.volume || 0);

      candles.push({
        open: prices[0],
        high: Math.max(...prices),
        low: Math.min(...prices),
        close: prices[prices.length - 1],
        volume: volumes.reduce((sum, v) => sum + v, 0),
      });
    }

    return candles;
  };

  if (error) {
    return (
      <div
        style={{
          width: "100%",
          height: height,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          flexDirection: "column",
          gap: 8,
          color: "#ef4444",
          fontSize: 12,
          background: "#0f172a",
          borderRadius: "8px",
        }}
      >
        <div>图表错误: {error}</div>
        <div style={{ fontSize: 10, color: "#9ca3af" }}>数据点数量: {series.length}</div>
      </div>
    );
  }

  if (series.length === 0) {
    return (
      <div
        style={{
          width: "100%",
          height: height,
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          color: "#9ca3af",
          fontSize: 12,
          background: "#0f172a",
          borderRadius: "8px",
        }}
      >
        等待数据加载... (当前数据点: {series.length})
      </div>
    );
  }

  return (
    <div
      style={{
        width: "100%",
        height: typeof height === "number" ? `${height}px` : height || "400px",
        minHeight: typeof height === "number" ? `${height}px` : height || "400px",
        position: "relative",
        background: "#0f172a",
        borderRadius: "8px",
      }}
    >
      <div 
        ref={chartRef} 
        style={{ 
          width: "100%", 
          height: "100%",
          minHeight: typeof height === "number" ? `${height}px` : height || "400px",
        }} 
      />
    </div>
  );
};
